#include <iostream>
#include <sys/mman.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <string>
#include <fcntl.h>

#define PAGE_SIZE 4096

// write_map filename
int main(int argc, char* argv[])
{
    if(argc != 2){
        std::cout << "Usage: " << argv[0] << " filename" << std::endl;
        return -1;
    }

    // 1. 打开文件目标（mmap 需要自己先打开文件）
    int fd = open(argv[1], O_RDWR | O_CREAT | O_TRUNC, 0666);
    if(fd < 0){
        std::cout << "open error: " << argv[1] << std::endl;
        return 1;
    }

    // 2. 默认文件大小是 0，无法和mmap 进行映射
    // 手动调整文件大小，方便进行合法映射，用 0 值填充
    if(ftruncate(fd, PAGE_SIZE) == -1)
    {
        std::cout << "munmap error: " << argv[1] << std::endl;
        return 2;
    }

    // 3. 文件映射
    char *shmaddr = (char*)::mmap(NULL, PAGE_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
    if(shmaddr == MAP_FAILED){
        std::cout << "mmap error: " << argv[1] << std::endl;
        return 3;
    }
    
    // 4. 进行文件操作
    for(char c = 'a'; c <= 'z'; c++){
        shmaddr[c - 'a'] = c;
        // sleep(1);
    }

    // 5. 关闭映射
    if(::munmap(shmaddr, PAGE_SIZE) == -1)
    {
        std::cout << "munmap error: " << argv[1] << std::endl;
        return 5;
    }

    ::close(fd);
    return 0;
}